package com.zyn.inventory.management.dao;


import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.transaction.annotation.Transactional;

import com.mysema.query.jpa.JPQLTemplates;
import com.mysema.query.jpa.impl.JPADeleteClause;
import com.mysema.query.jpa.impl.JPAQuery;
import com.mysema.query.jpa.impl.JPASubQuery;
import com.mysema.query.types.EntityPath;
import com.zyn.inventory.management.utils.CommonUtils;

@Transactional
public abstract class BaseDaoImpl<Entity> implements BaseDao<Entity> {
	@PersistenceContext
	private EntityManager entityManager;

	private Class<Entity> entityClass;

	public BaseDaoImpl() {
		this.entityClass = CommonUtils.getSuperClassGenricType(getClass());
	}

	protected final EntityManager getEntityManager() {
		return entityManager;
	}

	/**
	 * @return JPAQuery with the default JPQLTemplate to provide operator
	 *         patterns for JPQL
	 */
	public JPAQuery query() {
		return new JPAQuery(getEntityManager(), JPQLTemplates.DEFAULT);
	}

	/**
	 * @return JPASubQuery
	 */
	public JPASubQuery subQuery() {
		return new JPASubQuery();
	}

	/**
	 * @return JPAQuery with a hint to set the query as cacheable
	 */
	public JPAQuery cacheableQuery() {
		JPAQuery query = query();
		query.setHint("org.hibernate.cacheable", true);
		return query;
	}

	/**
	 * 
	 * @param entityPath
	 *            EntityPath
	 * @return EntityPath
	 */
	public JPADeleteClause deleteClause(EntityPath<?> entityPath) {
		return new JPADeleteClause(getEntityManager(), entityPath);
	}

	public void add(Entity entity) {
		this.entityManager.persist(entity);
	}

	public Entity get(Long pk) {
		return this.entityManager.find(entityClass, pk);
	}

	public void delete(Entity entity) {
		this.entityManager.remove(entity);
	}

	public void update(Entity entity) {
		this.entityManager.merge(entity);
	}

	public void deleteById(Long pk) {
		this.delete(get(pk));
	}

}
